package priv.pfz.basedao.jdbctemplate.dao;

import javax.annotation.Nonnull;
import java.util.List;

/**
 * @author yyjxp
 * 2024/8/3 23:55
 */
public interface SimpleBaseDao<Entity> {
    /**
     * insert一条记录
     * entity中为空的字段不会保存
     * INSERT INTO table (a,b,c) VALUES (entity.a, entity.b, entity.c)
     */
    int insert(@Nonnull Entity entity);

    /**
     * 批量insert多条记录
     * 以第一个entity中非空字段为模板批量保存
     * INSERT INTO table (a,b,c) VALUES (entity1.a, entity1.b, entity1.c), (entity2.a, entity2.b, entity2.c), ...
     */
    int batchInsert(@Nonnull Iterable<Entity> entities);

    /**
     * 按id更新一条记录
     * entity中为空的字段不会更新
     * UPDATE table SET a=entity.a, b=entity.b WHERE id=entity.id
     */
    int updateById(@Nonnull Entity entity);

    /**
     * 按Entity中标注了@UniqueKey的字段更新一条记录
     * entity中为空的字段不会更新
     * UPDATE table SET a=entity.a, b=entity.b WHERE uk=entity.uk
     */
    int updateByUniqueKey(@Nonnull Entity entity);

    /**
     * 将example匹配的记录更新为entity
     * example中为空的字段不会作为查询条件，entity中为空的字段不会更新
     * UPDATE table SET a=entity.a, b=entity.b WHERE b=example.b AND c=example.c
     */
    int updateByExample(@Nonnull Entity entity, @Nonnull Entity example);

    /**
     * 将examples匹配的记录更新为entity
     * example中为空的字段不会作为查询条件，entity中为空的字段不会更新
     * UPDATE table SET a=entity.a, b=entity.b
     * WHERE (b=example1.b AND c=example1.c) OR (c=example2.c AND d=example2.d) OR ...
     */
    int updateByExamples(@Nonnull Entity entity, @Nonnull Iterable<Entity> examples);

    /**
     * 按id查询一条记录
     * SELECT a,b,c FROM table WHERE id=#{id}
     */
    Entity selectById(long id);

    /**
     * 按ids批量查询多条记录
     * SELECT a,b,c FROM table WHERE id in ids
     */
    List<Entity> listByIds(@Nonnull Iterable<Long> ids);

    /**
     * 按example中的条件查询第一条记录
     * example中为空的字段不会作为查询条件
     * SELECT a,b,c FROM table WHERE a=example.a AND b=example.b LIMIT 1
     */
    Entity selectByExample(@Nonnull Entity example);

    /**
     * 按example中的条件查询多条记录
     * example中为空的字段不会作为查询条件
     * SELECT a,b,c FROM table WHERE a=example.a AND b=example.b
     */
    List<Entity> listByExample(@Nonnull Entity example);

    /**
     * 按examples中的条件查询多条记录
     * example中为空的字段不会作为查询条件
     * SELECT a,b,c FROM table WHERE (a=example1.a AND b=example1.b) OR (b=example2.b AND c=example2.c) OR ...
     */
    List<Entity> listByExamples(@Nonnull Iterable<Entity> examples);

    /**
     * 查询全表数量
     * SELECT count(*) FROM table
     */
    int countAll();

    /**
     * 查询全表所有记录
     * SELECT a,b,c FROM table
     */
    List<Entity> listAll();

    /**
     * 按id删除一条记录
     * DELETE FROM table WHERE id=#{id}
     */
    int deleteById(long id);

    /**
     * 按ids批量删除多条记录
     * DELETE FROM table WHERE id in ids
     */
    int deleteByIds(@Nonnull Iterable<Long> ids);

    /**
     * 按example中的条件删除多条记录
     * example中为空的字段不会作为删除条件
     * DELETE FROM table WHERE a=example.a AND b=example.b
     */
    int deleteByExample(@Nonnull Entity example);

    /**
     * 按examples中的条件删除多条记录
     * example中为空的字段不会作为删除条件
     * DELETE FROM table WHERE (a=example1.a AND b=example1.b) OR (b=example2.b AND c=example2.c) OR ...
     */
    int deleteByExamples(@Nonnull Iterable<Entity> examples);

    /**
     * 循环插入
     */
    int loopInsert(@Nonnull Iterable<Entity> entities);

    /**
     * 尝试插入，唯一键冲突时按id更新
     */
    int saveById(@Nonnull Entity entity);

    /**
     * 尝试插入，唯一键冲突时按唯一键更新
     */
    int saveByUniqueKey(@Nonnull Entity entity);

    /**
     * 尝试插入，唯一键冲突时按id更新
     */
    int batchSaveById(@Nonnull Iterable<Entity> entities);

    /**
     * 尝试插入，唯一键冲突时按唯一键更新
     */
    int batchSaveByUniqueKey(@Nonnull Iterable<Entity> entities);
}
